Container Control and Callback

Level: Advanced

by Brent Thorn [http://members.aol.com/b6sw/]

Home

Container Control

API Dialogs

Place a Dialog

Center a Dialog

LB IDE

Close Multiple Windows

TransparentBlt

Animation Control

Sprite Byte

Qcard DLL

Patterns and Music

Newsletter help

Index

For documentation and information about some of the methods employed in Brent's demo, see Creating Dialogs by API

'**********************************************************************
' Container Control Demo
' By Brent D. Thorn, Nov. 2004
' This code is released to the public domain.
' No credit to the author is necessary.
'**********************************************************************

    If Val(Version$) < 4 Then
        Notice "Code requires LB 4.0 or later."
        End
    End If

    Global ghContainer ' HWND of container.

    NoMainWin

    WindowWidth = 350
    WindowHeight = 350
    UpperLeftX = (DisplayWidth - WindowWidth) / 2
    UpperLeftY = (DisplayHeight - WindowHeight) / 2

    Button      #p.btn1, "Show Container", ShowHide, UL, 10, 20

    Checkbox    #p.chk1, "Checkbox", Handler1, Handler1, 10, 10, 100, 20
    RadioButton #p.opt1, "Top", ToTop, Handler1, 10, 30, 100, 20
    RadioButton #p.opt2, "Middle", ToMid, Handler1, 10, 50, 100, 20
    RadioButton #p.opt3, "Bottom", ToBot, Handler1, 10, 70, 100, 20

    Open "Container Demo" For Window As #p

    #p "TrapClose Quit"
    #p.opt1 "Set"

    ' Create a hidden container 150x150 in size.
    hInstance = GetWindowLong(HWnd(#p), _GWL_HINSTANCE)

    ghContainer = CreateContainer(0, 0, 150, 0, 150, 150, HWnd(#p), hInstance, 0)

    ' Have container "adopt" controls.
    Call SetParent HWnd(#p.chk1), ghContainer
    Call SetParent HWnd(#p.opt1), ghContainer
    Call SetParent HWnd(#p.opt2), ghContainer
    Call SetParent HWnd(#p.opt3), ghContainer

    Call DoEvents

Sub DoEvents
  [localLoop]
    Scan
    CallDLL #kernel32, "Sleep", 50 As Long, r As void
    GoTo [localLoop]
End Sub

Sub ShowHide Handle$
    CallDLL #user32, "IsWindowVisible", ghContainer As ULong,_
      itis As Long
    If itis Then
        cmd = _SW_HIDE
        #Handle$ "Show Container"
    Else
        cmd = _SW_SHOW
        #Handle$ "Hide Container"
    End If

    CallDLL #user32, "ShowWindow", ghContainer As ULong,_
    cmd As Long, r As Long
End Sub

Sub ToTop Handle$
    Call MoveWindow ghContainer, 150, 0
End Sub

Sub ToMid Handle$
    Call MoveWindow ghContainer, 150, 100
End Sub

Sub ToBot Handle$
    Call MoveWindow ghContainer, 150, 200
End Sub

Sub Quit Handle$
    Close #Handle$
    End
End Sub

Sub Handler1 Handle$
End Sub

'**********************************************************************
' Container Management
'**********************************************************************

Function CreateContainer( ExStyle, Style, X, Y, Width, Height, hParent, hInstance, lParam )
'-- Purpose:  Creates a child dialog box for use as a container object
'             for controls. Controls must be "adopted" using SetParent.
'-- Returns:  Window handle (HWND) of the newly-created container.
'-- Depends:  ContainerProc(), HIWORD(), LOWORD(), MulDiv()

    ' Get dialog base units.
    ' They're used to convert pixels to dialog units.
    CallDLL #user32, "GetDialogBaseUnits", r As ULong
    baseX = LOWORD(r)
    baseY = HIWORD(r)

    ' Initialize dialog template struct.
    Struct DLGTEMPLATE, _
        style As ULong, _
        dwExtendedStyle As ULong, _
        cdit As Word, _
        x As Short, _
        y As Short, _
        cx As Short, _
        cy As Short, _
        menus As Word, _ 'pseudo element
        class As Word, _ 'pseudo element
        title As Word    'pseudo element

    DLGTEMPLATE.style.struct = Style Or _WS_CHILDWINDOW Or _DS_CONTROL
    DLGTEMPLATE.dwExtendedStyle.struct = ExStyle Or _WS_EX_CONTROLPARENT
    DLGTEMPLATE.cdit.struct = 0
    DLGTEMPLATE.x.struct = MulDiv(X, 4, baseX)
    DLGTEMPLATE.y.struct = MulDiv(Y, 8, baseY)
    DLGTEMPLATE.cx.struct = MulDiv(Width, 4, baseX)
    DLGTEMPLATE.cy.struct = MulDiv(Height, 8, baseY)
    DLGTEMPLATE.menus.struct = 0
    DLGTEMPLATE.class.struct = 0
    DLGTEMPLATE.title.struct = 0

    ' Template must be in global memory space.
    cbDT = Len(DLGTEMPLATE.struct)
    CallDLL #kernel32, "GlobalAlloc", _GMEM_MOVEABLE As ULong,_
     cbDT As ULong, hDT As ULong
    CallDLL #kernel32, "GlobalLock", hDT As ULong, pDT As ULong

    ' Copy struct to global memory.
    CallDLL #kernel32, "RtlMoveMemory", pDT As ULong, DLGTEMPLATE As Struct,_
    cbDT As Long, r As void

    ' Get pointer to ContainerProc().
    Callback lpDlgProc, ContainerProc( ULong, ULong, ULong, ULong ), ULong

    ' Create the modeless, child dialog box.
    CallDLL #user32, "CreateDialogIndirectParamA", hInstance As Long,_
    pDT As ULong, hParent As ULong, lpDlgProc As ULong, lParam As Long,_
    hDlg As ULong

    ' Memory is no longer needed. Let's clean up.
    CallDLL #kernel32, "GlobalUnlock", hDT As ULong, r As Long
    CallDLL #kernel32, "GlobalFree", hDT As ULong, r As ULong

    ' Return dialog's window handle.
    CreateContainer = hDlg
End Function

Function ContainerProc( hDlg, uMsg, wParam, lParam )
'-- Purpose:  Acts as container dialog box's dialog procedure (DLGPROC).
'             Forwards WM_COMMAND and WM_NOTIFY messages to the container's
'             parent window.

    Select Case uMsg
    Case _WM_COMMAND, _WM_NOTIFY
        CallDLL #user32, "GetParent", hDlg As ULong, hParent As Ulong
        CallDLL #user32, "SendMessageA", hParent As ULong,_
        uMsg As ULong, wParam As ULong, lParam As ULong, r As Long
    End Select
End Function

'***********************************************
' Support Procedures
'***********************************************

Function HIWORD( dw )
    HIWORD = (dw And 4294901760) / 65536
End Function

Function LOWORD( dw )
    LOWORD = (dw And 65535)
End Function

Function GetWindowLong( hWnd, Index )
    CallDLL #user32, "GetWindowLongA",_
    hWnd As ULong, Index As Long,_
    GetWindowLong As Long
End Function

Function MulDiv( Number, Numerator, Denominator )
    CallDLL #kernel32, "MulDiv", Number As Long,_
    Numerator As Long, Denominator As Long,_
    MulDiv As Long
End Function

Sub MoveWindow hWnd, X, Y
    flags = _SWP_NOZORDER Or _SWP_NOSIZE
    CallDLL #user32, "SetWindowPos", hWnd As ULong,_
    _NULL As ULong, X As Long, Y As Long, 0 As Long,_
    0 As Long, flags As Long, r As Long
End Sub

Sub SetParent hWnd, hNewParent
    CallDLL #user32, "SetParent", hWnd As ULong,_
     hNewParent As ULong, r As ULong
End Sub


Home

Container Control

API Dialogs

Place a Dialog

Center a Dialog

LB IDE

Close Multiple Windows

TransparentBlt

Animation Control

Sprite Byte

Qcard DLL

Patterns and Music

Newsletter help

Index